/*eslint no-console: ["error", { allow: ["warn", "error", "log"] }] */

const request = require('request')
const iconv = require('iconv-lite')
const BufferHelper = require('bufferhelper')
const tough = require('tough-cookie')

const Rsa = require('./rsa')
const FileCookieStore = require('./filestore')
const {username, password, cookie_file} = require('./config')

const {getCode, submitCode} = require('./code')

const rsa = new Rsa()
const Cookie = tough.Cookie
const cookieStore = cookie_file ? new FileCookieStore(cookie_file) : new tough.MemoryCookieStore()

const pbk = '9a39c3fefeadf3d194850ef3a1d707dfa7bec0609a60bfcc7fe4ce2c615908b9599c8911e800aff684f804413324dc6d9f982f437e95ad60327d221a00a2575324263477e4f6a15e3b56a315e0434266e092b2dd5a496d109cb15875256c73a2f0237c5332de28388693c643c8764f137e28e8220437f05b7659f58c4df94685'

rsa.setPublic(pbk, '10001')

function makeTaobaoLoginForm (username, password) {
    const TPL_password_2 = rsa.encrypt(password)
    return {
        TPL_username: username,
        TPL_password:'',
        ncoSig:'',
        ncoSessionid:'',
        ncoToken:'453b64214f90ca9f174c5c1a5f9bf1253225be12',
        slideCodeShow:false,
        useMobile:false,
        lang:'zh_CN',
        loginsite:0,
        newlogin:0,
        TPL_redirect_url:'http://www.alimama.com',
        from:'alimama',
        fc:'default',
        style:'mini',
        css_style:'alimama',
        keyLogin:false,
        qrLogin:true,
        newMini:false,
        newMini2:true,
        tid:'',
        loginType:3,
        minititle:'alimama',
        minipara:'',
        pstrong:'',
        sign:'',
        need_sign:'',
        isIgnore:'',
        full_redirect:true,
        sub_jump:'',
        popid:'',
        callback:'',
        guf:'',
        not_duplite_str:'',
        need_user_id:'',
        poy:'',
        gvfdcname:10,
        gvfdcre:'68747470733A2F2F7777772E616C696D616D612E636F6D2F696E6465782E68746D',
        from_encoding:'',
        sub:'',
        TPL_password_2: TPL_password_2,
        loginASR:1,
        loginASRSuc:1,
        allp:'',
        oslanguage:'zh-CN',
        sr:'1280*800',
        osVer:'macos|10.116',
        naviVer:'chrome|58.0302911',
        osACN:'Mozilla',
        osAV:'5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36',
        osPF:'MacIntel',
        miserHardInfo:'',
        appkey:'',
        nickLoginLink:'',
        mobileLoginLink:'https://login.taobao.com/member/login.jhtml?style=mini&newMini2=true&css_style=alimama&from=alimama&redirectURL=http://www.alimama.com&full_redirect=true&disableQuickLogin=true&useMobile=true'
    }
}

function extractAlimamaRedirectUrl(str) {
    for (const pattern of [
        /{redirectURL:'(.*)'}/,
        /self\.location\.href = "(.*)"/
    ]) {
        const result = pattern.exec(str)
        if (result && result[1]) {
            return result[1]
        }
    }
}

function saveCookie(res) {
    let cookies
    if (res.headers['set-cookie'] instanceof Array) {
        cookies = res.headers['set-cookie'].map(Cookie.parse)
    } else if (typeof res.headers['set-cookie'] === 'string') {
        cookies = [Cookie.parse(res.headers['set-cookie'])]
    } else {
        cookies = []
    }

    return (async function () {
        for (const cookie of cookies) {
            await new Promise((resolve) => {
                cookieStore.putCookie(cookie, resolve)
            })
        }
    })()
}

const userAgent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36'

function getLoginRedirectUrl(username, password) {
    const options = {
        url: 'https://login.taobao.com/member/login.jhtml?redirectURL=http://www.alimama.com',
        form: makeTaobaoLoginForm(username, password),
        headers: {
            'User-Agent': userAgent
        }
    }
    return new Promise((resolve, reject) => {
        const req = request.post(options)
        req.on('error', (err) => {
            reject(err)
        })

        req.on('response', (res) => {
            if (res.statusCode !== 200) {
                reject(res)
                return
            }

            const bufferHelper = new BufferHelper()
            res.on('data', (chunk) => {
                bufferHelper.concat(chunk)
            })

            res.on('end', () => {
                const result = iconv.decode(bufferHelper.toBuffer(), 'GBK')
                const redirectUrl = extractAlimamaRedirectUrl(result)
                if (!redirectUrl) {
                    console.log(result)
                    reject('获取阿里妈妈跳转 url 失败')
                    return
                }

                resolve(saveCookie(res).then(() => redirectUrl))
            })
        })
    })
}


async function loginAlimama(username, password) {
    const redirectUrl = await getLoginRedirectUrl(username, password)
    function login(url) {
        return new Promise((resolve, reject) => {
            request({
                url,
                jar: request.jar(cookieStore),
                headers: {
                    'User-Agent': userAgent
                }
            }, (err, res) => {
                if (err) {
                    return reject(err)
                }

                const cookie = saveCookie(res)
                console.log(res.req)

                let result

                result = /iframe src="([^"]*)"/.exec(res.body)
                if (result && result[1]) {
                    return resolve(cookie.then(()=>login(result[1])))
                }

                result = /window\.location\.href = "(.*&umidfg=1)"/.exec(res.body)
                if (result && result[1]) {
                    return resolve(cookie.then(()=>login(result[1])))
                }

                result = /name="_fm\.v\._0\.h" value="([^"]*)"/.exec(res.body)
                if (result && result[1]) {
                    const verifyUrl = `https://passport.taobao.com/iv/mini/identity_verify.htm?tag=8&htoken=${result[1]}&appName=`
                    console.log(verifyUrl)
                    return resolve(cookie.then(()=>getCode(verifyUrl).then(code => submitCode(verifyUrl, code))))
                }

                resolve(cookie)
            })
        })
    }
    await login(redirectUrl)
}

exports.request = async function (url) {
    let loginCount = 0
    function _request(url) {
        return new Promise((resolve, reject) => {
            request({
                url,
                jar: request.jar(cookieStore),
                headers: {
                    'User-Agent': userAgent
                }
            }, (err, res, body) => {
                if (err) {
                    reject(err)
                    return
                }

                // 未登录
                if (res.req.path.indexOf('/member/login.htm') !== -1) {
                    if (++loginCount > 1) {
                        reject('登录阿里妈妈失败')
                    } else {
                        resolve(loginAlimama(username, password).then(()=> {
                            return _request(url)
                        }))
                    }
                } else {
                    resolve(body)
                }
            })
        })
    }

    return await _request(url)
}
